/// @file sensorplot.cpp
/// @brief Implementation of the sensorPlot class
/// @date 02/02/2010
/// @author Cédric Bardet, Reds, Heig-vd

#include "sensorplot.h"
#include "ui_sensorplot.h"
//#include "analyser.h"
#include "serializer.h"
#include "utils/myMath.h"

#include <QFileDialog>
#include <QFile>
#include <QMessageBox>

//*************************************************************************************************
// Constructor
//*************************************************************************************************
sensorPlot::sensorPlot(QWidget *parent) :
    QDialog(parent),
   m_ui(new Ui::sensorPlot)

{

    gData = new sensorPlot::graphData;

    m_ui->setupUi(this);

    myPlot = new QwtPlot((QWidget*) this);
    myPlot->setAxisTitle(QwtPlot::xBottom, QString("lastest %1 values").arg(nbr));
    myPlot->setAxisTitle(QwtPlot::yLeft, "acc m/s^2");
    myPlot->setAxisMaxMajor(QwtPlot::xBottom, 5);
    myPlot->setAxisMaxMajor(QwtPlot::yLeft, 5);
    m_ui->gridLayout->addWidget(myPlot);

    curve1 = new QwtPlotCurve("X");
    curve2 = new QwtPlotCurve("Y");
    curve3 = new QwtPlotCurve("Z");
    curveinit = new QwtPlotCurve("xyaxe");

    gData->axemax[0]=-3;
    gData->axemax[1]=3;
        for (int i=2;i<nbr;i++){
        gData->axemax[i]=1;
    }
    for (int i=0;i<nbr;i++){
        gData->time[i]=i;
    }
    curve1->setPen(QPen (Qt::red));
    //curve1->setSamples(gData->time,gData->x,nbr);
    curve1->attach(myPlot);
    curve2->setPen(QPen (Qt::green));
    //curve2->setSamples(gData->time,gData->y,nbr);
    curve2->attach(myPlot);
    curve3->setPen(QPen (Qt::blue));
   // curve3->setSamples(gData->time,gData->z,nbr);
    curve3->attach(myPlot);

    curveinit->setVisible(false);
    curveinit->setSamples(gData->time,gData->axemax,nbr);
    curveinit->attach(myPlot);

     nbCurrentCommand=1;
     nbCurrentSample=1;

     QString str;
     str.setNum(nbCurrentCommand);
     m_ui->label_commandNBR->setText(str);
     m_ui->label_sampleNBR->setText(str);
     m_ui->pushButton_5->setEnabled(false);

     ser = new Serializer("RawData.txt");
     ser->saveTo("RawData.txt");

  connect(&m_Timer, SIGNAL(timeout()), this, SLOT(running()));

}
//*************************************************************************************************
// Destructor
//*************************************************************************************************
sensorPlot::~sensorPlot()
{
    m_Timer.stop();
    delete m_ui;
}
//*************************************************************************************************
// Function init gData
/// @param newone bool
/// @return gData
//*************************************************************************************************
sensorPlot::graphData* sensorPlot::init(bool newone)
{
    if (newone){
    	sensorPlot::graphData *gData = new sensorPlot::graphData;

    	return gData;
    }
    else
        return gData;
}
//*************************************************************************************************
// Function changeEvent
/// @param QEvent
//*************************************************************************************************
void sensorPlot::changeEvent(QEvent *e)
{

    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

//*************************************************************************************************
// Function running
//*************************************************************************************************
void sensorPlot::running()
{

if (m_Timer.isActive())

    {
        sensorPlot::graphData *gData= init(false);

        bool print=true;
        emit printAction(gData,print);

        curve1->setSamples(gData->time,gData->x,nbr);

        curve1->attach(myPlot);

        curve2->setSamples(gData->time,gData->y,nbr);

        curve2->attach(myPlot);

        curve3->setSamples(gData->time,gData->z,nbr);
        curve3->attach(myPlot);
        myPlot->replot();

        // Update the 2 progress bars
        if (m_ui->checkBox->isChecked())
        {
            double outVal[3];
            if (runNetwork(outVal))
            {
                m_ui->progressBar->setValue(100 * (outVal[0]));
                m_ui->progressBar_2->setValue(100 * (outVal[1]));
				m_ui->progressBar_3->setValue(100 * (outVal[2]));
            }
        }
   }
}



//*************************************************************************************************
// Function exec
//*************************************************************************************************
int sensorPlot::exec(const QString& sensorPlot)
{
    m_sensorPlot = sensorPlot;

    QDialog::exec();

    return QDialog::Accepted;
}


//*************************************************************************************************
// Function on click button close
//*************************************************************************************************
void sensorPlot::on_pushButton_clicked()
{
    close();
}


//*************************************************************************************************
// Function on click button latest 100
//*************************************************************************************************
void sensorPlot::on_pushButton_2_clicked()
{
  sensorPlot::graphData *gData= init(false);
    bool print=true;
    emit printAction(gData,print);

    curve1->setSamples(gData->time,gData->x,nbr);
    curve1->attach(myPlot);
    curve2->setSamples(gData->time,gData->y,nbr);
    curve2->attach(myPlot);
    curve3->setSamples(gData->time,gData->z,nbr);
    curve3->attach(myPlot);

    m_ui->pushButton_5->setEnabled(true);

    myPlot->replot();

 }


//*************************************************************************************************
// Function on Click button run
//*************************************************************************************************

void sensorPlot::on_pushButton_3_clicked()
{
    m_ui->pushButton_5->setEnabled(false);
    m_ui->pushButton_2->setEnabled(false);
 m_Timer.start(100);
}

//*************************************************************************************************
// Function on Click button stop
//*************************************************************************************************
void sensorPlot::on_pushButton_4_clicked()
{
    m_ui->pushButton_5->setEnabled(true);
    m_ui->pushButton_2->setEnabled(true);
   m_Timer.stop();
}

//*************************************************************************************************
// Function on Click button save Sample
//*************************************************************************************************
void sensorPlot::on_pushButton_5_clicked()
{

    sensorPlot::graphData *gData= init(false);


    ser->logSampleNBR(nbCurrentCommand,nbCurrentSample);
    ser->logSampleData(gData->x,nbr);
    ser->logSampleData(gData->y,nbr);
    ser->logSampleData(gData->z,nbr);

   nbCurrentSample++;
   if (nbCurrentSample==maxSamples+1){
       nbCurrentSample=1;
       nbCurrentCommand++;
   }

   QString str;


   str.setNum(nbCurrentCommand);
   m_ui->label_commandNBR->setText(str);
   str.setNum(nbCurrentSample);
   m_ui->label_sampleNBR->setText(str);


   m_ui->pushButton_5->setEnabled(false);
   if (nbCurrentCommand==maxCommands+1){
       m_ui->pushButton_5->setText("Finished");
       str.setNum(0);
       m_ui->label_commandNBR->setText(str);
       m_ui->label_sampleNBR->setText(str);
       ser->close();
       printf("Max Number Samples reached\n");
       return;
   }

}

//*************************************************************************************************
// Function on Click button load network params
//*************************************************************************************************
void sensorPlot::on_pushButton_6_clicked()
{
    QFileDialog dial;
    QFile file(dial.getOpenFileName(this, QString("Load network parameters")));

    // Open the file
    if (!file.open(QFile::ReadOnly))
        return;

    QTextStream stream(&file);
    QString line = stream.readLine();

    // Check file type
    if (line.compare("FENNIX Network Weights File") != 0)
    {
        QMessageBox::critical(NULL, "File error", "Not a FENNIX file");
        return;
    }

    // Go to the first Layer
    while (stream.readLine().compare("Indexes") != 0);

    // Get the number of neurons
    int layers = 0;
    int neurons[5]; // Max layers at this moment

    while (!stream.readLine().isEmpty())
    {
        line = stream.readLine();
        neurons[layers] = line.trimmed().split("\t").size();
        layers++;
    }

    // Create the network
    _network.createNetwork(layers, neurons);

    // Set the weights
    int i=0;
    while (!(line = stream.readLine()).isNull())
    {
        QStringList list = line.trimmed().split("\t");
        for (int j=0; j<list.size(); j++)
            _network.setWeight(i, j, ((QString) list.at(j)).toDouble());

        i++;
    }

    QMessageBox::information(NULL, "File loaded", "File successfully loaded");
}

//*************************************************************************************************
// Function on Click button run network
//*************************************************************************************************
void sensorPlot::on_pushButton_7_clicked()
{
    QString str1, str2,str3;
    double outVal[3];

    if (runNetwork(outVal))
        QMessageBox::information(NULL, "", "Output values : " + str1.setNum(outVal[0]) + " ,  " + str2.setNum(outVal[1])+ " ,  " + str3.setNum(outVal[2]));
}

//*************************************************************************************************
// Function runNetwork
//*************************************************************************************************
bool sensorPlot::runNetwork(double* outputs)
{
    // Get the 100 last values from sensor
    sensorPlot::graphData *gData= init(false);
    double inVal[10];

    // Calculate the min/mean/max values
   /* inVal[0] = Math::dmin(gData->x, nbr);
    inVal[1] = Math::dmax(gData->x, nbr);
    inVal[2] = Math::dmean(gData->x, nbr);

    inVal[3] = Math::dmin(gData->y, nbr);
    inVal[4] = Math::dmax(gData->y, nbr);
    inVal[5] = Math::dmean(gData->y, nbr);

    inVal[6] = Math::dmin(gData->z, nbr);
    inVal[7] = Math::dmax(gData->z, nbr);
    inVal[8] = Math::dmean(gData->z, nbr);
	*/


	inVal[0] = Math::dmin(gData->y, nbr);
    inVal[1] = Math::dmax(gData->y, nbr);
    inVal[2] = Math::dmean(gData->y, nbr);
	inVal[3] = Math::dmin(gData->z, nbr);
    inVal[4] = Math::dmax(gData->z, nbr);
    inVal[5] = Math::dmean(gData->z, nbr);

    // Feed the neural network with the values
    return _network.runNetwork(inVal, outputs);
}

